fix: check transaction ID when matching RejectedInput in HTTP handler#21
fix: check transaction ID when matching RejectedInput in HTTP handler#21
Conversation
Under high load with concurrent TX submissions, the HTTP handler for POST /transaction was matching ANY RejectedInput for NewTx, not checking if it was the specific transaction submitted. This caused false-negative responses where a successful TX was reported as rejected because another concurrent TX was rejected. Now the handler checks txId transaction == txid before returning SubmitTxRejected, preventing the race condition.
Adds a test that verifies the HTTP handler correctly ignores RejectedInput events for different transactions. This ensures that when TX_A is submitted and a RejectedInput for TX_B appears, the handler for TX_A continues waiting and correctly returns success when TX_A is confirmed.
GitHub Actions runners have limited disk space (~14GB available). When building uncached Nix derivations (like our modified hydra-node), the build can exhaust disk space during compilation. This adds a cleanup step that removes unused tools before the build: - .NET SDK (~1.8GB) - Android SDK (~9GB) - GHC (~5GB) - CodeQL (~2.5GB) - Unused Docker images This frees up ~20GB of disk space, ensuring builds complete successfully.
Transaction costsSizes and execution budgets for Hydra protocol transactions. Note that unlisted parameters are currently using
Script summary
|
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 5837 | 10.59 | 3.36 | 0.52 |
| 2 | 6035 | 12.46 | 3.94 | 0.54 |
| 3 | 6236 | 14.71 | 4.65 | 0.58 |
| 5 | 6638 | 18.43 | 5.81 | 0.63 |
| 10 | 7646 | 29.14 | 9.19 | 0.79 |
| 43 | 14281 | 98.99 | 30.94 | 1.80 |
Commit transaction costs
This uses ada-only outputs for better comparability.
| UTxO | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 561 | 2.44 | 1.16 | 0.20 |
| 2 | 739 | 3.38 | 1.73 | 0.22 |
| 3 | 919 | 4.36 | 2.33 | 0.24 |
| 5 | 1279 | 6.41 | 3.60 | 0.28 |
| 10 | 2181 | 12.13 | 7.25 | 0.40 |
| 54 | 10051 | 98.61 | 68.52 | 1.88 |
CollectCom transaction costs
| Parties | UTxO (bytes) | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|---|
| 1 | 56 | 524 | 25.20 | 7.30 | 0.43 |
| 2 | 114 | 636 | 32.27 | 9.39 | 0.51 |
| 3 | 170 | 747 | 42.72 | 12.29 | 0.62 |
| 4 | 227 | 858 | 52.58 | 15.06 | 0.72 |
| 5 | 283 | 969 | 62.77 | 17.93 | 0.83 |
| 6 | 338 | 1081 | 64.20 | 18.57 | 0.85 |
| 7 | 393 | 1192 | 86.64 | 24.41 | 1.08 |
| 8 | 453 | 1307 | 82.47 | 23.81 | 1.05 |
Cost of Increment Transaction
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 1785 | 24.00 | 7.62 | 0.48 |
| 2 | 1945 | 25.43 | 8.68 | 0.50 |
| 3 | 2074 | 26.86 | 9.75 | 0.53 |
| 5 | 2275 | 28.94 | 11.66 | 0.57 |
| 10 | 3090 | 39.81 | 18.02 | 0.74 |
| 40 | 7779 | 99.31 | 54.60 | 1.69 |
Cost of Decrement Transaction
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 618 | 22.57 | 7.33 | 0.41 |
| 2 | 693 | 22.62 | 7.95 | 0.42 |
| 3 | 985 | 28.07 | 10.17 | 0.49 |
| 5 | 1272 | 30.87 | 12.29 | 0.54 |
| 10 | 2135 | 41.94 | 18.70 | 0.72 |
| 40 | 6626 | 98.31 | 54.37 | 1.63 |
Close transaction costs
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 694 | 27.50 | 8.46 | 0.46 |
| 2 | 770 | 28.47 | 9.38 | 0.48 |
| 3 | 868 | 31.97 | 11.00 | 0.53 |
| 5 | 1307 | 37.73 | 13.99 | 0.61 |
| 10 | 2034 | 47.97 | 20.21 | 0.77 |
| 35 | 5723 | 95.03 | 50.09 | 1.53 |
Contest transaction costs
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 680 | 33.87 | 10.16 | 0.53 |
| 2 | 803 | 35.85 | 11.38 | 0.56 |
| 3 | 941 | 37.84 | 12.60 | 0.59 |
| 5 | 1304 | 43.24 | 15.47 | 0.67 |
| 10 | 1903 | 52.41 | 21.32 | 0.81 |
| 29 | 4715 | 96.61 | 46.25 | 1.47 |
Abort transaction costs
There is some variation due to the random mixture of initial and already committed outputs.
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 5805 | 27.09 | 9.10 | 0.69 |
| 2 | 5914 | 35.88 | 12.07 | 0.79 |
| 3 | 6131 | 46.04 | 15.52 | 0.90 |
| 4 | 6231 | 53.83 | 18.11 | 0.99 |
| 5 | 6414 | 64.16 | 21.62 | 1.11 |
| 6 | 6645 | 74.71 | 25.22 | 1.23 |
| 7 | 6843 | 85.13 | 28.82 | 1.35 |
| 8 | 6810 | 90.78 | 30.53 | 1.40 |
| 9 | 6983 | 98.14 | 33.02 | 1.49 |
FanOut transaction costs
Involves spending head output and burning head tokens. Uses ada-only UTXO for better comparability.
| Parties | UTxO | UTxO (bytes) | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|---|---|
| 10 | 0 | 0 | 5834 | 19.19 | 6.41 | 0.61 |
| 10 | 30 | 1707 | 6853 | 80.48 | 30.61 | 1.32 |
| 10 | 39 | 2222 | 7162 | 98.05 | 37.58 | 1.53 |
End-to-end benchmark results
This page is intended to collect the latest end-to-end benchmark results produced by Hydra's continuous integration (CI) system from the latest master code.
Please note that these results are approximate as they are currently produced from limited cloud VMs and not controlled hardware. Rather than focusing on the absolute results, the emphasis should be on relative results, such as how the timings for a scenario evolve as the code changes.
Generated at 2026-01-07 00:32:15.626768417 UTC
Baseline Scenario
| Number of nodes | 1 |
|---|---|
| Number of txs | 300 |
| Avg. Confirmation Time (ms) | 5.546850953 |
| P99 | 7.666376839999999ms |
| P95 | 6.759430700000001ms |
| P50 | 5.372172ms |
| Number of Invalid txs | 0 |
Three local nodes
| Number of nodes | 3 |
|---|---|
| Number of txs | 900 |
| Avg. Confirmation Time (ms) | 32.945929657 |
| P99 | 48.81705894999998ms |
| P95 | 43.16166175ms |
| P50 | 31.736067ms |
| Number of Invalid txs | 0 |
Transaction cost differencesNo cost or size differences found |
Summary
Problem
When submitting transactions via HTTP, the handler waits for either
TxValidorTxInvalidresponses. However, it wasn't checking the transaction ID, so aRejectedInputfrom a previous transaction could be incorrectly matched to the current transaction, causing spuriousSubmitTxRejectederrors.Solution
Check that the transaction ID in the
TxInvalidresponse matches the submitted transaction before treating it as a rejection.Changes
TxInvalidresponsesRelated
feature/datum-cache-memory-optimization